package othello.players.benchmarkplayers;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import othello.model.Action;
import othello.model.IBoard;
import othello.players.AbstractPlayer;
import othello.players.learnplayers.AbstractNeuralNetworkPlayer.BenchmarkState;


/**
 * Implements positional strategy from Van Eck paper
 */

public class HEUR extends AbstractPlayer {
    
    private static final int[][] positionValues =
		new int[][]{{100,-25, 10,  5,  5, 10,-25,100},
                     {-25,-25,  2,  2,  2,  2,-25,-25},
                     { 10,  2,  5,  1,  1,  5,  2, 10},
                     {  5,  2,  1,  2,  2,  1,  2,  5},
                     {  5,  2,  1,  2,  2,  1,  2,  5},
                     { 10,  2,  5,  1,  1,  5,  2, 10},
                     {-25,-25,  2,  2,  2,  2,-25,-25},
                     {100,-25, 10,  5,  5, 10,-25,100}};

    public HEUR() {
        super("HEUR");
    }

    private int positionOccupance(IBoard brd, int r, int c) {
        Color color = brd.playerAt(r,c);
        if (color == null){
            return 0;
        }
        if (color.equals(this.getColor())) {
            return 1;
        }
        
        return -1;
    }
    
    private double percentOccupied(IBoard brd){
        double count = 0.0;
        for (int r = 0; r < brd.getRowCount(); r++) {
            for (int c = 0; c < brd.getColCount(); c++) {
                count += positionOccupance(brd,r,c)*positionOccupance(brd,r,c);
            }
        }                    
        return (count/64d)*100d;
    }
    
    boolean checkEndGame(IBoard brd) {
        int cornersCovered  =   positionOccupance(brd,0,0)*positionOccupance(brd,0,0) +
                                positionOccupance(brd,0,7)*positionOccupance(brd,0,7) +
                                positionOccupance(brd,7,0)*positionOccupance(brd,7,0) +
                                positionOccupance(brd,7,7)*positionOccupance(brd,7,7);
                                
        return (cornersCovered == 4) || (percentOccupied(brd) >= 80.0) ;
    }
    
    @Override
	public void endGame() {
	}
    
    public int evalWeighted(IBoard brd) {
        int eval = 0;
        for (int r = 0; r < brd.getRowCount(); r++) {
            for (int c = 0; c < brd.getColCount(); c++) {
                eval += positionValues[r][c]*positionOccupance(brd,r,c);
            }
        }
        return eval;
    }
    
    public int evalEndgame(IBoard brd) {
        int eval = 0;
        for (int r = 0; r < brd.getRowCount(); r++) {
            for (int c = 0; c < brd.getColCount(); c++) {
                eval += positionOccupance(brd,r,c);
            }
        }
        return eval;
    }
    
    @Override
    public void beginTurn() {
    	
    	//if(false){
    	if (board.getTurns() < 8 && board.getBenchmarkstate() == BenchmarkState.Benchmarking && board.getRandFirstFourMoves()){
    		List<Action> availableActions = getAvailableActions(board);
            Action bestAction = null;
            Random generator = new Random();
            
            if (!availableActions.isEmpty()){
            	bestAction = availableActions.get(generator.nextInt(availableActions.size()));
            	//System.out.println("debug> " + board.getTurns() + " turns passed so " + this.name + "makes a random move.");
            	board.placePiece(this, bestAction.getRow(), bestAction.getCol());
            }
            
    	} else {                
	        // Determine the valid move with the maximal evaluation function
	        int maxEval = Integer.MIN_VALUE;
	        int bestR = -1;
	        int bestC = -1;
	        int eval;
	        boolean inEndGame = checkEndGame(board);        
	        
	        for (int r = 0; r < board.getRowCount(); r++) {
	            for (int c = 0; c < board.getColCount(); c++) {
	                if (board.isValidMove(getColor(), r, c)) {    
	                    IBoard hypoBrd = board.hypotheticallyPlacePiece(this.getColor(), r, c);	        	                    
	                    eval = evalWeighted(hypoBrd);	                    
	                    if (eval > maxEval){
	                        maxEval = eval;
	                        bestR = r;
	                        bestC = c;
	                    }
	                }
	            }         
	        }
	        
	        if (bestR > -1){
	            board.placePiece(this,bestR,bestC);
	        }
    	}
        
        // Aparently there are no valid moves, so pass.
        board.pass(this);
    }
    
    

    @Override
    public void endTurn() {
    }    

}
